﻿using System.Collections.Generic;
using System.Drawing;
using ImageQuantization;

namespace CsPotrace
{
    public class Quantize
    {
        private static int distRGB(Color rgb1, Color rgb2)
        {
            return
              (rgb1.R - rgb2.R) * (rgb1.R - rgb2.R)
            + (rgb1.G - rgb2.G) * (rgb1.G - rgb2.G)
            + (rgb1.B - rgb2.B) * (rgb1.B - rgb2.B);
        }

        /**
         * find the index of closest color in a palette
         */
        private static int findRGB(Color[] rgbpal, int ncolor,Color rgb)
        {
            //assert(ncolor > 0);
            //assert(rgbpal);
            int index = -1, dist = 0;
            for (int k = 0; k < ncolor; k++)
            {
                int d = distRGB(rgbpal[k], rgb);
                if (index == -1 || d < dist) { dist = d; index = k; }
            }
            return index;
        }
        public static IndexedMap rgbMapQuantize(Bitmap rgbmap, int ncolor)
        {
            rgbmap.Save("rgbmap.JPG");
            OctreeQuantizer quantizer = new OctreeQuantizer(ncolor, 8);
            Bitmap quantized = quantizer.Quantize(rgbmap);
            quantized.Save("quantized.JPG");
            IndexedMap newmap = new IndexedMap(rgbmap.Width,rgbmap.Height);
            newmap.nrColors = ncolor;
            for (int i = 0; i < ncolor; i++)
            {
                newmap.clut[i] = quantized.Palette.Entries[i];
            }
            // fill in new map pixels
            for (int y = 0; y < rgbmap.Height; y++)
            {
                for (int x = 0; x < rgbmap.Width; x++)
                {
                    Color rgb = rgbmap.GetPixel(x, y);
                    int index = findRGB(newmap.clut, ncolor,rgb);
                    newmap.SetPixel(x, y, index);
                }
            }
            return newmap;
        }
    }
}
